import {Config} from "./Config";
import {Menu} from "../expressExt/Menu";
import * as fs from "fs";

export class mysqlModel {

    static outMenu = Menu.root + "/runtime/models/";
    static dbClassName = "db.ts";

    static cacheTableMap = {
        // ts_goods_pic: "gid",
    }

    static getTable(name:string):string {
        return mysqlModel.cacheTableMap[name];
        // for (let u of mysqlModel.cacheId) {
        //     if (u[0] == name)
        //         return u;
        // }
        // return null;
    }

    /**
     * 创建db class
     * @param tables
     */
    static dbClass(tables:string[]) {
        let code = `
import {Config} from "../configExt/Config";
import {SqlBuilder} from "../expressExt/db/SqlBuilder";`;
        for (let s of tables) {
            code += `
import {${s}} from "./${s}";`
        }

        code += `

export class db {

`
        for (let s of tables) {
            code += `

    /**
     *
     */
    static get ${s}():SqlBuilder<${s}> {
        return new SqlBuilder(${s}, Config.mysql);
    }`
        }

        code += `
}`

        fs.writeFile(mysqlModel.outMenu + mysqlModel.dbClassName, code);
    }

    /**
     * 创建表model
     * @param table
     * @param info
     */
    static tableClass(table:string, info:FieldInfo[]) {
        let code = `
import {sql} from "../expressExt/db/Isql";

export class ${table} {
`

        for (let field of info) {

            /**
             * 字段的类型,缺省值
             */
            let type = "string";
            let def = `""`;

            if (field.Type.indexOf("int") >= 0 || field.Type.indexOf("double") >= 0 || field.Type.indexOf("float") >= 0) {
                type = "number";
                if (field.Default != null)
                    def = field.Default + "";
                else
                    def = "0";
            }
            else if (field.Type.indexOf("date") >= 0) {
                type = "Date";
                def = "new Date()";
            }
            else {
                type = "string";
                if (field.Default != null)
                    def = `"${field.Default}"`;
            }

            code += `

    /**
     * ${field.Comment}
     */`
            if (field.Key == "PRI") {
                code += `
    @sql.primaryKey`
                // def = "null"
            }


            if (field.Extra == "auto_increment") {
                code += `
    @sql.autoIncrement`;
                // def = "null"
            }

            // if (field.Field.indexOf("time") >= 0) {
            //     def = "Date.now()";
            // }

            let cache = mysqlModel.getTable(table);
            if (cache && cache == field.Field) {
                code += `
    @sql.cacheId`;
            }

            code += `
    ${field.Field}:${type} = ${def};`
        }

        code += `


    toString() {
        return JSON.stringify(this);
    }

}`

        fs.writeFile(mysqlModel.outMenu + table + ".ts", code);
    }


    static start() {

        if (fs.existsSync(mysqlModel.outMenu + mysqlModel.dbClassName))
            return;


        if (!fs.existsSync(mysqlModel.outMenu)) {
            fs.mkdirSync(mysqlModel.outMenu);
        }


        let tables:string[] = []
        Config.mysql.query("show TABLE status", res=> {
            if (res.err)
                return;

            for (let u of res.data!) {
                // for (let k in u) {
                tables.push(u["Name"]);
                // }
            }
            mysqlModel.dbClass(tables);

            for (let t of tables) {
                Config.mysql.query(`show full fields FROM ${t}`, res=> {
                    if (res.err)
                        return;
                    mysqlModel.tableClass(t, res.data!)
                });
            }

        });
    }


}


interface FieldInfo {
    Collation:string;
    Comment:string;
    Default:string;
    Extra:string;
    Field:string;
    Key:string;
    Null:string;
    Privileges:string;
    Type:string;
}